package com.example.java_chatroom.component;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.util.concurrent.ConcurrentHashMap;

// 本类用来记录当前用户在线的状态. (维护 userId 和 WebSocketSession 之间的映射)
@Slf4j
@Component
public class OnlineUserMapper {
    // 此处这个哈希表要考虑 线程安全 问题
    private ConcurrentHashMap<Integer, WebSocketSession> sessions = new ConcurrentHashMap<>();

    /**
     * 用户上线, 给哈希表里插入键值对
     * @param userId
     * @param webSocketSession
     */
    public void online(int userId, WebSocketSession webSocketSession) {
        if(sessions.get(userId) != null) {
            // 针对用户多开, 这里的处理是不记录后面登录用户的 session, 即后续登录用户做不到消息的收发
            // (毕竟这里是根据映射关系来实现消息转发的)
            log.info("[{}] 已登录, 登录失败",userId);
            return;
        }
        sessions.put(userId, webSocketSession);
        log.info("[{}] 上线!", userId);
    }


    /**
     * 用户下线, 根据 userId 删除键值对
     * @param userId
     * @param webSocketSession
     */
    public void offline(int userId, WebSocketSession webSocketSession) {
        if(sessions.get(userId) == webSocketSession) {
            // 如果键值对中 session和调用该方法的 session 相同, 才允许删除键值对
            sessions.remove(userId);
            log.info("[{}] 下线!", userId);
        }
    }

    /**
     * 根据 userId 获取键值对
     *
     * @param userId
     * @return
     */
    public WebSocketSession getSession(int userId) {
        return sessions.get(userId);
    }
}
